import math
import numpy as np
import sys
from sklearn.multiclass import OneVsRestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, f1_score
from sklearn.metrics import f1_score
from sklearn.utils import shuffle as skshuffle
from sklearn.preprocessing import MultiLabelBinarizer
from scipy.io import loadmat
import utils
from sklearn import svm


class NodeClassificationEval(object):
    def __init__(self, embed_filename, label, n_node, n_embed, n_classes, split, time):
        self.embed_filename = embed_filename  # each line: node_id, embeddings(dim: n_embed)
        self.n_node = n_node
        self.n_embed = n_embed
        self.n_classes = n_classes
        self.emd = utils.read_embeddings(embed_filename, n_node=n_node, n_embed=n_embed)
        self.label = label
        self.split = split
        self.time = time

    def eval_node_classification(self):
        train_num = int(self.emd.shape[0] * self.split)

        accuracy = 0.
        micro_score = 0.
        macro_score = 0.

        for i in range(self.time):
            permutation = np.random.permutation(self.emd.shape[0])
            self.emd = self.emd[permutation]
            self.label = self.label[permutation]

            x_train, y_train = self.emd[:train_num], self.label[:train_num]
            x_test, y_test = self.emd[train_num:], self.label[train_num:]
            clf = svm.SVC(gamma='auto')
            clf.fit(x_train, y_train)
            y_pred = clf.predict(x_test)
            accuracy += accuracy_score(y_test, y_pred)
            micro_score += f1_score(y_test, y_pred, average='micro')
            macro_score += f1_score(y_test, y_pred, average='macro')
        return accuracy / self.time, micro_score / self.time, macro_score / self.time
